<html>
  <head>
    <meta charset="utf-8" />
    <title>凯晖科技数据展示平台</title>
    <script src="./static/jquery.min.js"></script>
    <script src="./static/vue.js"></script>
    <link rel="stylesheet" type="text/css" href="./static/index.css" />
    <link rel="stylesheet" type="text/css" href="./static/layui/layui.css" />
  </head>
  <body>
    <style>
      .kanban {
        width: 100%;
        height: 100%;
        background-image: url(./static/images/bg.jpg);
        background-size: cover;
        color: #666666;
      }
      .main {
        width: 100%;
        height: 100%;
      }
      .canvas {
        position: absolute;
        width: 100%;
        height: 100%;
        left: 0;
        top: 0;
        z-index: 1;
      }
      .small-font {
        font-size: 0.6rem !important;
      }
      .normal-font {
        font-size: 0.8rem !important;
      }
      .big-font {
        font-size: 1rem !important;
      }

      .header {
        height: 4rem;
        background: url(./static/images/head_bg.png) no-repeat center center;
        background-size: 100% 100%;
        position: relative;
        z-index: 100;
      }
      .header h1 {
        color: #fff;
        text-align: center;
        font-size: 1.3rem;
        line-height: 4rem;
        cursor: pointer;
      }
      .logo {
        background-image: url(./static/images/kh_logo.png);
        background-repeat: no-repeat;
        background-size: auto 60%;
        position: absolute;
        left: 1rem;
        top: 1rem;
        padding-top: 1rem;
        height: 3rem;
        width: 10rem;
        z-index: 200;
      }
      .now-time {
        position: absolute;
        right: 1rem;
        top: 1rem;
        height: 2rem;
        color: #bbbbbb;
        font-size: 1rem;
        line-height: 2rem;
        z-index: 200;
      }

      .bar-row {
        display: flex;
        padding: 0;
        margin-top: 0;
        margin-bottom: 0.8rem;
      }
      .barbox {
        padding: 0;
        flex: 1;
        margin-right: 0.8rem;
        position: relative;
      }
      .barbox:last-child {
        margin-right: 0;
      }
      .barbox:before,
      .barbox:after {
        position: absolute;
        width: 1.2rem;
        height: 0.4rem;
        content: '';
      }
      .barbox:before {
        border-left: 2px solid #02a6b5;
        left: 0;
        border-top: 2px solid #02a6b5;
      }
      .barbox:after {
        border-right: 2px solid #02a6b5;
        right: 0;
        bottom: 0;
        border-bottom: 2px solid #02a6b5;
      }
      .barbox li {
        width: 50%;
        text-align: center;
        position: relative;
        z-index: 100;
        background: rgba(0, 255, 255, 0.2);
        line-height: 3rem;
      }
      .barbox li .title {
        font-size: 1.2rem;
        color: rgba(255, 255, 255, 0.8);
      }
      .barbox li .counter {
        font-size: 1.2rem;
        /* font-family: electronicFont; */
        font-weight: bold;
      }
      .barbox li:first-child:before {
        position: absolute;
        content: '';
        height: 50%;
        width: 1px;
        background: rgba(255, 255, 255, 0.2);
        right: 0;
        top: 25%;
      }

      .content {
        padding: 0 0.8rem;
      }

      .boxall {
        width: 100%;
        height: 100%;
        border: 1px solid rgba(25, 186, 139, 0.17);
        padding: 0 0.8rem;
        background: rgba(255, 255, 255, 0.04) url(./static/images/line.png);
        background-size: 100% auto;
        position: relative;
        z-index: 10;
      }
      .boxall:before,
      .boxall:after {
        position: absolute;
        width: 0.6rem;
        height: 0.6rem;
        content: '';
        border-top: 2px solid #02a6b5;
        top: 0;
      }
      .boxall:before,
      .boxfoot:before {
        border-left: 2px solid #02a6b5;
        left: 0;
      }
      .boxall:after,
      .boxfoot:after {
        border-right: 2px solid #02a6b5;
        right: 0;
      }
      .alltitle {
        font-size: 0.8rem;
        color: #fff;
        text-align: center;
        line-height: 2rem;
      }
      .allnav {
        height: calc(100% - 2rem);
        overflow: hidden;
      }
      .allnav .layui-table {
        margin: 0;
      }
      .allnav .layui-table,
      .allnav .layui-table tbody tr:hover {
        background-color: transparent;
        color: #ccc;
      }
      .allnav .layui-table thead tr {
        background-color: rgba(0, 255, 255, 0.2);
      }
      .allnav .layui-table[lay-even] tr:nth-child(even) {
        background-color: rgba(0, 255, 255, 0.2);
      }
      .allnav .layui-table td {
        text-align: center;
        font-size: 1rem;
        line-height: 3rem;
        padding: 0;
      }
      .allnav .layui-table th {
        text-align: center;
        color: #02a6b5;
        font-weight: 800;
        font-size: 1rem;
        line-height: 3rem;
        padding: 0;
      }
      .boxfoot {
        position: absolute;
        bottom: 0;
        width: 100%;
        left: 0;
      }
      .boxfoot:before,
      .boxfoot:after {
        position: absolute;
        width: 0.6rem;
        height: 0.6rem;
        content: '';
        border-bottom: 2px solid #02a6b5;
        bottom: 0;
      }
      .footer {
        height: 1rem;
        padding: 0.2rem 0;
        font-size: 0.6rem;
        text-align: center;
        color: #bbbbbb;
      }
      .avatar {
        background-size: cover;
        background-repeat: no-repeat;
        background-position: center;
        margin: 1rem auto;
        width: 6rem;
        height: 6rem;
        border-radius: 50%;
      }
    </style>
    <!-- <div class="canvas" style="opacity: 0.2;">
      <iframe frameborder="0" src="./background.html" style="width: 100%; height: 100%;"></iframe>
    </div> -->
    <div id="app" class="kanban">
      <div class="logo"></div>
      <div class="now-time"><span>{{showData.today}}</span></div>
      <div id="selectOrgArea" style="width: 100%;min-height: 12rem;padding: 1rem;display: none;">
        <div style="padding:0.2rem;width: 33%;display:inline-block;" v-for="(d,i) in orglist" :key="i">
          <button style="width: 100%;" type="button" @click.prevent="chooseOrg(d)" class="layui-btn layui-btn-primary">
            {{d.line_name}}
          </button>
        </div>
      </div>
      <div class="main">
        <div class="header">
          <h1 @click="selectOrg">{{orgName}}&nbsp;{{kanbanTitle}}</h1>
        </div>
        <div class="content flex" style="height:calc(100% - 5.2rem);">
          <div style="width: calc(50% - 0.4rem);height:100%;margin-right: 0.8rem;">
            <div class="bar-row">
              <div class="barbox">
                <ul class="clearfix" style="color:#FFB800;">
                  <li class="pull-left">
                    <span class="title">机种</span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="counter"
                      >{{showData.summary.model_code}}</span
                    >
                  </li>
                  <li class="pull-left">
                    <span class="title">料号</span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="counter"
                      >{{showData.summary.sku_code}}</span
                    >
                  </li>
                </ul>
              </div>
            </div>
            <div style="width: 100%;height: calc(100% - 4.3rem);">
              <div style="height: calc(60% - 0.4rem);margin-bottom: 0.8rem;">
                <div class="boxall">
                  <div class="alltitle">课时目标产出</div>
                  <div class="allnav">
                    <div id="chart0" style="height:100%;"></div>
                  </div>
                  <div class="boxfoot"></div>
                </div>
              </div>
              <div style="height: calc(40% - 0.4rem);" class="flex">
                <div style="width: calc(50% - 0.4rem);height:100%;margin-right:0.8rem;">
                  <div class="boxall">
                    <div class="alltitle">总达成率</div>
                    <div class="allnav">
                      <div id="chart1" style="height:calc(100% - 1.6rem);"></div>
                      <div style="line-height: 2rem;text-align: center;color: #bbb;margin-top: -0.8rem;">
                        目标:{{showData.outputData.output_target}} &nbsp;&nbsp;&nbsp;&nbsp;
                        实际:{{showData.outputData.act_output_qty}}
                      </div>
                    </div>
                    <div class="boxfoot"></div>
                  </div>
                </div>
                <div style="width: calc(50% - 0.4rem);height:100%;">
                  <div class="boxall">
                    <div class="alltitle">一次通过率</div>
                    <div class="allnav">
                      <div id="chart2" style="height:calc(100% - 1.6rem);"></div>
                      <div style="line-height: 2rem;text-align: center;color: #bbb;margin-top: -0.8rem;">
                        目标:{{showData.qualityData.fpy_target}}% &nbsp;&nbsp;&nbsp;&nbsp;
                        实际:{{showData.qualityData.fpy}}%
                      </div>
                    </div>
                    <div class="boxfoot"></div>
                  </div>
                </div>
              </div>
            </div>
          </div>
          <div style="width: calc(50% - 0.4rem);height:100%;">
            <div style="height: calc(45% - 0.4rem);margin-bottom:0.8rem;">
              <div class="boxall" id="wipbox">
                <div class="alltitle">工程人员信息</div>
                <div class="allnav">
                  <table class="layui-table" lay-skin="nob">
                    <thead>
                      <tr>
                        <th v-for="(d,i) in showData.persons" :key="i">{{d.param_value}}</th>
                      </tr>
                    </thead>
                    <tbody>
                      <tr>
                        <td v-for="(d,i) in showData.persons" :key="i">
                          <div style="line-height: 2rem;">
                            <div class="avatar" :style="{'backgroundImage':'url(' + d.member_picture + ')'}"></div>
                            <p>{{d.member_name}}</p>
                            <p>{{d.tel_no}}</p>
                          </div>
                        </td>
                      </tr>
                    </tbody>
                  </table>
                </div>
                <div class="boxfoot"></div>
              </div>
            </div>
            <div style="height: calc(55% - 0.4rem);">
              <div class="boxall" id="linebox">
                <div class="alltitle">在制工单投入情况</div>
                <div class="allnav">
                  <table class="layui-table" lay-even lay-skin="nob">
                    <thead>
                      <tr>
                        <th>生产任务单</th>
                        <th>机种</th>
                        <th>计划数量</th>
                        <th>投入数量</th>
                        <th>投入率</th>
                      </tr>
                    </thead>
                    <tbody>
                      <tr v-for="(d,i) in showmoData" :key="i">
                        <td>{{d.mo_no}}</td>
                        <td>{{d.model_name}}</td>
                        <td>{{d.target_qty}}</td>
                        <td>{{d.input_qty}}</td>
                        <td style="padding-right: 10px;">
                          <div
                            class="layui-progress layui-progress-big"
                            style="background-color: #999999;overflow: hidden;"
                          >
                            <div
                              class="layui-progress-bar"
                              :class="d.input_rate>80?'layui-bg-green':(d.input_rate>60?'layui-bg-orange':'layui-bg-red')"
                              :style="{width:d.input_rate + '%'}"
                            >
                              <span class="layui-progress-text">{{d.input_rate + '%'}}</span>
                            </div>
                          </div>
                        </td>
                      </tr>
                    </tbody>
                  </table>
                </div>
                <div class="boxfoot"></div>
              </div>
            </div>
          </div>
        </div>
        <div class="footer">合肥智慧云上信息技术有限公司 技术支持</div>
      </div>
    </div>
  </body>
  <script src="./static/lodash.min.js"></script>
  <script src="./static/dayjs.js"></script>
  <script src="./static/layui/layer.js"></script>
  <script src="./static/echarts/echarts.min.js"></script>
  <script src="./static/echarts/my-echarts-theme.js"></script>
  <script>
    var URL = 'http://' + location.hostname + ':8080/mes_api'
    // URL = 'http://47.100.246.49:8080/mes_api'
    var storageKey = 'kanban_default_line'
    var token = null

    //根据窗口宽度动态设置根节点的字体大小
    var remPx = 12
    function setRem() {
      var html = document.getElementsByTagName('html')[0]
      var oWidth = document.body.clientWidth || document.documentElement.clientWidth
      remPx = parseInt(oWidth / 80)
      html.style.fontSize = remPx + 'px'
    }
    setRem()

    //Echarts
    var chart0 = {}
    var chart1 = {}
    var chart2 = {}
    var chart0_default_option = {
      grid: {
        top: '15%',
        bottom: '30%'
      },
      legend: {
        show: true,
        textStyle: { color: '#eeeeee' }
      },
      dataset: {
        dimensions: ['shift_start_end', 'output_target', 'act_output_qty'],
        source: []
      },
      xAxis: [
        {
          type: 'category',
          axisLabel: { fontSize: this.remPx * 0.8, color: '#eeeeee', rotate: 45 }
        }
      ],
      yAxis: [
        {
          type: 'value',
          axisLine: { show: false },
          axisLabel: { show: false },
          splitLine: { show: false }
        }
      ],
      series: [
        {
          name: '目标值',
          type: 'line',
          label: {
            show: true,
            position: 'top',
            fontSize: this.remPx * 0.8,
            color: '#eeeeee'
          }
        },
        {
          name: '实际值',
          type: 'bar',
          barMaxWidth: '30%',
          label: {
            show: true,
            position: 'insideTop',
            fontSize: this.remPx * 0.8,
            color: '#eeeeee'
          }
        }
      ]
    }
    var chart1_default_option = {
      series: [
        {
          name: 'chart1',
          type: 'gauge',
          min: 0,
          max: 100,
          splitNumber: 5,
          radius: '90%',
          axisLine: {
            // 坐标轴线
            lineStyle: {
              // 属性lineStyle控制线条样式
              color: [[1, 'green']],
              width: 2,
              shadowColor: '#fff', //默认透明
              shadowBlur: 5
            }
          },
          axisLabel: {
            // 坐标轴小标记
            fontWeight: 'bolder',
            color: '#fff',
            shadowColor: '#fff', //默认透明
            shadowBlur: 5
          },
          axisTick: {
            // 坐标轴小标记
            length: 8, // 属性length控制线长
            lineStyle: {
              // 属性lineStyle控制线条样式
              color: 'auto',
              shadowColor: '#fff', //默认透明
              shadowBlur: 5
            },
            splitNumber: 4
          },
          splitLine: {
            // 分隔线
            length: 10, // 属性length控制线长
            lineStyle: {
              // 属性lineStyle（详见lineStyle）控制线条样式
              width: 3,
              color: '#fff',
              shadowColor: '#fff', //默认透明
              shadowBlur: 10
            }
          },
          pointer: {
            // 分隔线
            shadowColor: '#fff', //默认透明
            shadowBlur: 5
          },
          title: {
            textStyle: {
              // 其余属性默认使用全局文本样式，详见TEXTSTYLE
              fontWeight: 'bolder',
              fontSize: 20,
              fontStyle: 'italic',
              color: '#fff',
              shadowColor: '#fff', //默认透明
              shadowBlur: 10
            }
          },
          detail: {
            offsetCenter: [0, '70%'], // x, y，单位px
            textStyle: {
              // 其余属性默认使用全局文本样式，详见TEXTSTYLE
              fontWeight: 'bolder',
              fontSize: 1.2 * remPx,
              color: '#FFB800',
              fontFamily: 'electronicFont'
            },
            formatter: function(v) {
              return v + '%'
            }
          },
          data: [{ value: 0 }]
        }
      ]
    }
    var chart2_default_option = {
      series: [
        {
          name: 'chart2',
          type: 'gauge',
          min: 80,
          max: 100,
          splitNumber: 4,
          radius: '90%',
          axisLine: {
            // 坐标轴线
            lineStyle: {
              // 属性lineStyle控制线条样式
              color: [
                [0.75, 'red'],
                [1, 'green']
              ],
              width: 2,
              shadowColor: '#fff', //默认透明
              shadowBlur: 5
            }
          },
          axisLabel: {
            // 坐标轴小标记
            fontWeight: 'bolder',
            color: '#fff',
            shadowColor: '#fff', //默认透明
            shadowBlur: 5
          },
          axisTick: {
            // 坐标轴小标记
            length: 8, // 属性length控制线长
            lineStyle: {
              // 属性lineStyle控制线条样式
              color: 'auto',
              shadowColor: '#fff', //默认透明
              shadowBlur: 5
            },
            splitNumber: 5
          },
          splitLine: {
            // 分隔线
            length: 10, // 属性length控制线长
            lineStyle: {
              // 属性lineStyle（详见lineStyle）控制线条样式
              width: 3,
              color: '#fff',
              shadowColor: '#fff', //默认透明
              shadowBlur: 10
            }
          },
          pointer: {
            // 分隔线
            shadowColor: '#fff', //默认透明
            shadowBlur: 5
          },
          title: {
            textStyle: {
              // 其余属性默认使用全局文本样式，详见TEXTSTYLE
              fontWeight: 'bolder',
              fontSize: 20,
              fontStyle: 'italic',
              color: '#fff',
              shadowColor: '#fff', //默认透明
              shadowBlur: 10
            }
          },
          detail: {
            offsetCenter: [0, '70%'], // x, y，单位px
            textStyle: {
              // 其余属性默认使用全局文本样式，详见TEXTSTYLE
              fontWeight: 'bolder',
              fontSize: 1.2 * remPx,
              color: '#FFB800',
              fontFamily: 'electronicFont'
            },
            formatter: function(v) {
              return v + '%'
            }
          },
          data: [{ value: 0 }]
        }
      ]
    }

    //列表滚动计算准备
    var lineMaxRow = 1
    function calRows() {
      var linebox = document.querySelector('#linebox>.allnav')
      var theadHeight = linebox.querySelector('table>thead').clientHeight
      lineMaxRow = parseInt(linebox.clientHeight / theadHeight) - 1
      lineMaxRow = lineMaxRow > 1 ? lineMaxRow : 1
    }

    //窗口大小变化监听
    window.onresize = function() {
      setRem()
      calRows()
      chart0.resize()
      chart1.resize()
      chart2.resize()
    }

    var app = new Vue({
      el: '#app',
      data: function() {
        return {
          remPx: remPx, //根字体大小px
          orgId: '', //组织ID 暂时用不到
          orgName: '', //组织名称
          kanbanTitle: '数据展示平台',
          timer: null, //拉取数据定时器
          timerScroll: null, //表格滚动定时器
          showData: {
            today: '2020-01-01 12:00',
            summary: {
              sku_code: '',
              model_code: ''
            },
            moData: [],
            outputData: { output_target: 0, act_output_qty: 0, output_rate: 100 },
            qualityData: { fpy_target: 80, fpy: 100 },
            persons: []
          },
          showmoData: [],
          orglist: [],
          selectOrgLayerIndex: null //组织选择框的层id
        }
      },
      methods: {
        selectOrg: function() {
          //打开组织选择框
          this.selectOrgLayerIndex = layer.open({
            type: 1,
            title: '请选择数据范围',
            closeBtn: false,
            area: [54 * remPx + 'px'],
            btn: '取消',
            shade: 0.8,
            content: $('#selectOrgArea'),
            cancel: function() {}
          })
        },
        chooseOrg: function(d) {
          this.orgName = d.line_name
          this.orgId = d.id
          localStorage.setItem(storageKey, JSON.stringify(d))
          this.refreshData() //选了线别之后重新拉取数据
          layer.close(this.selectOrgLayerIndex)
        },
        initCharts: function() {
          chart0 = echarts.init(document.getElementById('chart0'), 'mytheme')
          chart0.setOption(chart0_default_option)
          chart1 = echarts.init(document.getElementById('chart1'), 'mytheme')
          chart1.setOption(chart1_default_option)
          chart2 = echarts.init(document.getElementById('chart2'), 'mytheme')
          chart2.setOption(chart2_default_option)
        },
        refreshData: function() {
          var that = this
          clearTimeout(this.timer) //清除定时器
          //获取时间
          $.ajax(URL + '/platform/time/sync', {
            type: 'get',
            headers: { token: token },
            success: function(r) {
              that.showData.today = r
            }
          })
          //获取当前生产产品信息
          $.ajax(URL + '/kbn/production/getlist', {
            type: 'get',
            data: { line: that.orgName },
            headers: { token: token },
            success: function(r) {
              that.showData.summary = r ? r : {}
            }
          })
          //获取课时投入产出
          $.ajax(URL + '/kbn/class_output/line/getlist', {
            type: 'get',
            data: { line: that.orgName },
            headers: { token: token },
            success: function(r) {
              // var tmp = [
              //   { shift_start_end: '1', output_target: 100, act_output_qty: 103 },
              //   { shift_start_end: '2', output_target: 100, act_output_qty: 94 },
              //   { shift_start_end: '3', output_target: 100, act_output_qty: 98 },
              //   { shift_start_end: '4', output_target: 100, act_output_qty: 0 },
              // ]
              chart0.setOption({ dataset: { source: r.datas } })
            }
          })
          //获取工程人员信息
          $.ajax(URL + '/kbn/engineer/line/getlist', {
            type: 'get',
            data: { line: that.orgName },
            headers: { token: token },
            success: function(r) {
              that.showData.persons = r.datas
            }
          })
          //获取工单在制情况
          $.ajax(URL + '/kbn/wip_summary/wip/mo/getlist', {
            type: 'get',
            data: { line: that.orgName },
            headers: { token: token },
            success: function(r) {
              that.showData.moData = r.datas
              that.showTableScrollData()
            }
          })
          //获取总投入产出
          $.ajax(URL + '/kbn/ttl_output/line/getlist', {
            type: 'get',
            data: { line: that.orgName },
            headers: { token: token },
            success: function(r) {
              that.showData.outputData = r ? r : {}
              chart1.setOption({
                series: [{ name: 'chart1', data: [{ value: that.showData.outputData.output_rate }] }]
              })
            }
          })
          //获取通过率
          $.ajax(URL + '/kbn/yield_rate/fpy/getlist', {
            type: 'get',
            data: { line: that.orgName },
            headers: { token: token },
            success: function(r) {
              that.showData.qualityData = r
              var redValue = (that.showData.qualityData.fpy_target - 80) / 20
              chart2.setOption({
                series: [
                  {
                    name: 'chart2',
                    data: [{ value: that.showData.qualityData.fpy }],
                    axisLine: {
                      lineStyle: {
                        color: [
                          [redValue, 'red'],
                          [1, 'green']
                        ]
                      }
                    }
                  }
                ]
              })
            }
          })
          //数据拉取请求全部发起完成
          this.timer = setTimeout(this.refreshData, 60000) //定时执行下次数据拉取
        },
        showTableScrollData: function() {
          clearTimeout(this.timerScroll) //清除定时器
          var that = this
          //line滚动处理
          if (this.showData.moData.length > lineMaxRow) {
            //总条目数大于可显示条目，需要滚动
            if (this.showmoData.length != lineMaxRow) {
              //窗口尺寸变化过，需要需要重新布局
              this.showmoData = _.slice(this.showData.moData, 0, lineMaxRow)
            } else {
              //找到已显示的最后一个数组元素
              var x = _.findIndex(that.showData.moData, function(o) {
                //依据主键字段
                return o.mo_no == _.last(that.showmoData).mo_no
              })
              x >= this.showData.moData.length - 1 ? (x = 0) : x++
              var tmp = _.drop(this.showmoData)
              tmp.push(this.showData.moData[x])
              this.showmoData = tmp
            }
          } else {
            this.showmoData = this.showData.moData
          }
          this.timerScroll = setTimeout(this.showTableScrollData, 2000) //2秒滚动一次
        }
      },
      mounted: function() {
        var that = this
        //初始化Echarts
        that.initCharts()
        //计算滚动行数
        calRows()
        //执行登录
        $.get(URL + '/platform/token/sysadmin/admin123', {}, function(r) {
          if (r.token) {
            token = r.token
            //获取线别列表
            $.ajax(URL + '/basicdata/line/getlistbypage?size=1000&page=1', {
              type: 'get',
              data: {},
              headers: { token: token },
              success: function(r) {
                that.orglist = r.pageRows
              }
            })
            //获取缓存默认的ORG数据
            var org = localStorage.getItem(storageKey)
            if (org) {
              org = JSON.parse(org)
              that.orgId = org.id
              that.orgName = org.line_name
              //启动拉取数据
              that.refreshData()
            } else {
              //打开组织选择框
              that.selectOrg()
            }
          } else {
            alert('用户身份验证失败')
          }
        })
      }
    })
  </script>
</html>
